<?
/**
* Пример:

$srewrite = new site_rewrite();
// Реврайт с урла http://realty.rufox.local/<city_eng_name>/ на
// http://realty.rufox.local/?Act=mycity&main_city=3707
$srewrite->addRewrite("/^(\/(?<city>[a-z\-]+))?\/my\/(?<Act>[^\/\?]+).*$/i", "/my/item.php", array(), 'main_city');
$srewrite->addRewrite("/^\/(?<city>[a-z\-]+)(\/)?$/i", "item.php", array('Act'=>'mycity'), 'main_city');
$srewrite->addRewrite("/^\/(?<city>[a-z\-]+)\/(?<path>[^\?]+).*$/i", "item.php", array(), 'main_city');
$output = $srewrite->run();

Специальные имена переменных:
city - английское название города
path - путь к скрипту

*/

class site_rewrite{
    private $document_root;
    private $rules = array();
    private $cities = array();
    public function __construct(){
        $this->setDocumentRoot($_SERVER['DOCUMENT_ROOT']);
    }
    
    public function setDocumentRoot($path){
        $this->document_root = $path;
    }
    
    /**
    * Добавить правило Rewrite
    * 
    * @param string $rule Шаблон вида "/^\/(?<Act>[a-z_]+)\/.*$/i"
    * @param string $script Имя скрипта, напрмер "index.php" или "dir/index.php"
    * @param array $static_get_params Неизменяемые переменные, появятся в массиве $_GET
    * @param string $city_param_name Имя GET параметра, в котором появится ID-города
    */
    public function addRewrite($rule, $script, $static_get_params = array(), $city_param_name = "city_id"){
        $this->rules[] = array( 
            'rule' => $rule,
            'script' => $script,
            'static_get_params' => $static_get_params,
            'city_param' => $city_param_name,
        );
    }
    
    public function run(){
        foreach($this->rules as $one){
            if(preg_match($one['rule'], $_SERVER['REQUEST_URI'], $matches)){
                // Специальный параметр city - говорит о том, что это английское имя горда
                if(!empty($matches['city'])){
                    $city_id = $this->getCityId($matches['city']);
                    if($city_id === false) continue; // Если город не найден, считаем, что правило не сработало
                    $_GET[$one['city_param']] = $city_id;
                    unset($matches['city']);
                }
                
                // Специальный параметр path - это путь к скрипту
                $path = "";
                if(!empty($matches['path'])){
                    $path = $matches['path'];
                    if(!is_dir($this->document_root.'/'.$path)) $path = "";
                    unset($matches['path']);
                }
                
                // Все найденные переменные с нечислвыми индексами помещаем в $_GET
                foreach($matches as $key=>$val)
                    if(!is_numeric($key)) $_GET[$key] = $val;

                // Добавляем статичные GET-параметры 
                $_GET = array_merge($_GET, $one['static_get_params']);

                // Синхронизируем массив $_REQUEST
                $_REQUEST = array_merge($_REQUEST, $_GET);

                $full_script_name = realpath($this->document_root.'/'.$path.'/'.$one['script']);
                ob_start();
                //echo($full_script_name);
                //print_r($_REQUEST);
                chdir(dirname($full_script_name)); // Переходим в папку скрипта (чтобы корректно работали относительные include (...)
                global_site_rewrite_include_function($full_script_name);
                return ob_get_clean();
            }
        }
        return false; // если ни одно правило не сработало
    }
    
    public function getCityId($city_eng){
        $this->loadCites();
        $city_eng = mb_strtolower($city_eng);
        if(!isset($this->cities[$city_eng])) return false;
        return $this->cities[$city_eng];
    }
    
    private function loadCites(){
        if(!empty($this->cities)) return;
        CDatabase::SQLExec("SELECT id, name_eng FROM `myrufox_passport`.`kos_cities` WHERE name_eng != ''");
        while ($row = CDatabase::FetchLine())
            $this->cities[mb_strtolower($row['name_eng'])] = $row['id'];
    }
}

function global_site_rewrite_include_function($file){
    include $file;
}